/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.diag.layer;

import java.io.*;
import java.util.*;
import java.awt.*;

import self.awt.*;
import self.gee.*;

import org.w3c.dom.Document;
import org.w3c.dom.*;

public class BasicDiagramLayer implements IDiagramLayer, Serializable {
	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
  private IDiagram  owner;
  private ArrayList elements = new ArrayList();

  public BasicDiagramLayer( IDiagram owningView ) {
    owner = owningView;
    PainterManager.registerOwner( this );
  }

  public void dump() {
    int max = elements.size();
    for ( int cntr = 0; cntr < max; cntr++ ) {
      IGraphicElement elem = (IGraphicElement) elements.get( cntr );
      System.out.println( cntr + ": " + elem );
    }
  }

  // ILayer support
  public void paint( Graphics surface ) {
    int max = elements.size();
    for ( int cntr = 0; cntr < max; cntr++ ) {
      IGraphicElement elem = (IGraphicElement) elements.get( cntr );
      surface.setFont( owner.getFont() );
      elem.paint( surface );
    }
  }

  public void clear() {
    beginUpdate();
    elements.clear();
    endUpdate();
    owner.setDirty();
  }

  public boolean isVisible() {
    return true;
  }

  public void setVisible( boolean show ) {
	// nothing to do.
  }

  // IDiagramLayer support
  public IGraphicElement getElementAtPoint( Point target ) {
    int max = elements.size();
    for ( int cntr = max-1; cntr > -1; cntr-- ) {
      IGraphicElement elem = (IGraphicElement) elements.get( cntr );
      if ( elem.contains(target) )
        return elem;
    }
    return null;
  }

  public IGraphicElement getElementAtPoint( Point target, IGraphicElement otherThan ) {
    int max = elements.size();
    for ( int cntr = max-1; cntr > -1; cntr-- ) {
      IGraphicElement elem = (IGraphicElement) elements.get( cntr );
      if ( elem == otherThan )
        continue;
      if ( elem.contains(target) )
        return elem;
    }
    return null;
  }

  public void getElementWithinLasso( Rectangle target, java.util.List lasso ) {
    int max = elements.size();
    for ( int cntr = 0; cntr < max; cntr++ ) {
      IGraphicElement elem = (IGraphicElement) elements.get( cntr );
      if ( elem.isWithin(target) )
        lasso.add( elem );
    }
  }

  public IDiagram getDiagram() {
    return owner;
  }

  public void dispose() {
    PainterManager.unregisterOwner( this );
    elements.clear();
    elements = null;
    owner = null;
  }

  public void setDirty() {
    owner.setDirty();
  }

  public void addElement( IGraphicElement toAdd ) {
    if ( !(toAdd instanceof Serializable) )
      throw new IllegalArgumentException( "err.serializable.element" );
    if ( elements.contains(toAdd) )
      return;
    beginUpdate();
    elements.add( toAdd );
    endUpdate();
    setDirty();
  }

  public void removeElement( IGraphicElement toRemove ) {
    beginUpdate();
    elements.remove( toRemove );
    endUpdate();
    setDirty();
  }

  public void getElements( java.util.List store ) {
    store.addAll( elements );
  }

  public int  getElementCount() {
    return elements.size();
  }

  public void getElementsWithReferenceIds( java.util.Map idStore ) {
    int max = elements.size();
    for ( int cntr = 0; cntr < max; cntr++ ) {
      IGraphicElement elem = (IGraphicElement) elements.get( cntr );
      Integer chkId = new Integer(  elem.getReferenceId() );
      if ( idStore.containsKey(chkId) )
        idStore.put( chkId, elem );
    }
  }

  public void toBack( IGraphicElement toChg ) {
    int pos = elements.indexOf( toChg );
    if ( pos >= 0 ) {
      beginUpdate();
      elements.remove( pos );
      elements.add( 0, toChg );
      endUpdate();
      setDirty();
    }
  }

  public void toFront( IGraphicElement toChg ) {
    int pos = elements.indexOf( toChg );
    if ( pos >= 0 ) {
      beginUpdate();
      elements.remove( pos );
      elements.add( toChg );
      endUpdate();
      setDirty();
    }
  }

  public void moveForward( IGraphicElement toChg ) {
    int pos  = elements.indexOf( toChg );
    int last = elements.size()-1;
    if ( pos < last ) {
      beginUpdate();
      elements.remove( pos );
      elements.add( pos+1, toChg );
      endUpdate();
      setDirty();
    }
  }

  public void moveBackward( IGraphicElement toChg ) {
    int pos  = elements.indexOf( toChg );
    if ( pos > 0 ) {
      beginUpdate();
      elements.remove( pos );
      elements.add( pos-1, toChg );
      endUpdate();
      setDirty();
    }
  }

  public void beginUpdate() {
    owner.beginUpdate();
  }

  public void endUpdate() {
    owner.endUpdate();
  }

  public void readFrom( Node self, HashMap idObjLookUp ) throws DOMException {
    LayerPersistenceUtils.readFrom( self, idObjLookUp, this );
  }

  public void writeTo( Document doc, Element self, HashMap objIdLookup ) throws DOMException {
    LayerPersistenceUtils.writeTo( elements, doc, self, objIdLookup );
  }

  public void assignElements( java.util.List replacingElements ) {
    elements.clear();
    elements.addAll( replacingElements );
  }
}